Repository navigation
Conversation
This adds the CallFunction operation which takes a CircuitFunction reference as a parameter. The actual CircuitFunction is called upon _decompose_. This allows reusing blocks of gates without huge memory increases. Serialization will be added in a later commit.
This adds serialization to CallFunctionOperation. Notably, `CircuitFunction` now implements `SerializableByKey`, ensuring that a circuitfunction will not be serialized each time it is called.
The parameters of a decomposed CallFunctionOperation will be the parameters of the template circuit, minus the function parameters, plus the parameters in the invoked parameters.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8437 +/- ##
==========================================
- Coverage 99.58% 99.58% -0.01%
==========================================
Files 1137 1139 +2
Lines 105119 105594 +475
==========================================
+ Hits 104687 105158 +471
- Misses 432 436 +4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
dstrain115
left a comment
There was a problem hiding this comment.
A few edge cases from Mike and myself to look into, but overall the structure seems good to me. Excited to see this in action!
This adds the measurement_key_map and parent_path properties to CallFunctionOperation. This unifies the protocol interface and allows circuit functions to be called within circuitoperations with repetitions.
|
I added the measurement key related methods that were missing as pointed out by Mike (which will probably be necessary for QEC). This led to a bit of code duplication with |
mhucka
left a comment
There was a problem hiding this comment.
Nice work.
In addition to the notes below, Gemini had a suggestion for an architectural change:
CircuitFunction+CallFunctionOperationprovides two capabilities thatCircuitOperationdoes not have: (1) parameterized qubit placement viaVariableQidresolution, and (2)SerializableByKeydeduplication of theCircuitFunctiontemplate across calls with positionalfunction_args.- However, once
CircuitFunctionis defined,CallFunctionOperationis effectively a parameterized wrapper that produces aFrozenCircuit. Rather than re-implementing measurement key mapping,parent_path, and_extern_keysrescoping separately inCallFunctionOperation(which is where Finding 1 above arises),CallFunctionOperationcould either share the key-scoping helper functions withCircuitOperationor delegate measurement/control key scoping to an underlyingCircuitOperation(self._circuit_function.circuit, ...).
It sounds plausible, but you're the best judge of whether that's a good idea or not.
| def with_qubits(self, *new_qubits: cirq.Qid) -> CallFunctionOperation: | ||
| if tuple(new_qubits) == self._qubits: | ||
| return self | ||
| raise ValueError("CallFunctionOperation does not support `with_qubits`.") |
There was a problem hiding this comment.
Can you add a test case for what happens when a transformer is applied to something with a CallFunctionOperation and the result is subsequently simulated?
There was a problem hiding this comment.
I added a test for simulating a transformed CallFunctionOperation (although the currently used transformers do not use the with_qubits method tagged here).
with_qubits is enabled now using the underlying CircuitOperation and explicit tests were added. One thing to note is that qubit maps do not work with VariableQids currently, as they are currently broken in the CircuitOperation implementation. This should be fixed in a separate PR.
|
Converting to a draft while I consider a redesign. |
Rather than reimplement many methods, CallFunctionOperation now creates a CircuitOperation from the CircuitFunction upon initialization. This prevents excessive duplicate code.
|
I redesigned this as suggested, by adding a member variable
Several methods were implemented explicitly rather than delegating to the underlying Finally, |
This adds the experimental Cirq 2.0 feature
CallFunctionOperationwhichtakes a
CircuitFunctionand a set of parameters to call it with. The underlyingcircuit is not generated until
_decompose_. This allows for multiple calls toan underlying circuit without storing multiple copies of the circuit.